<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <button id="btn1">添加节流</button>
  <button id="btn2">添加防抖</button>
  <script>

    function handleClick(event) {
      console.log('更新DOM或发请求', this)
    }

    document.getElementById('btn1').onclick = throttle(handleClick, 2000)
    document.getElementById('btn2').onclick = debounce(handleClick, 2000)
    
    /* 
    用于产生节流函数的工具函数
    */
    function throttle (callback, delay) {
      // 用于保存处理事件的时间, 初始值为0, 保证第一次会执行
      let start = 0
      // 返回事件监听函数 ==> 每次事件发生都会执行
      return function (event) {
        console.log('---throttle')
        // 发生事件的当前时间
        const current = Date.now()
        // 与上一次处理事件的时差大于delay的时间
        if (current-start>delay) {
          // 执行处理事件的函数
          callback.call(event.target, event)
          // 保证当前时间
          start = current
        }
      }
    }

    /* 
    用于产生防抖函数的工具函数
    */
    function debounce (callback, delay) {
      let timeoutId
      // 返回事件监听函数 ==> 每次事件发生都会执行
      return function (event) {
        console.log('---debounce')
        // 如果还有未执行的定时器, 清除它
        if (timeoutId) {
          clearTimeout(timeoutId)
        }
        // 启动延时delay的定时器, 并保证定时器id
        timeoutId = setTimeout(() => {
          // 执行处理事件的函数
          callback.call(event.target, event)
          // 删除保存的定时器id
          timeoutId = undefined
        }, delay);
      }
    }
  </script>
</body>
</html>